﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenSSL.X509;
using OpenSSL.Crypto;
using OpenSSL.Core;
using System.IO;
using System.Configuration;
using Sicurezza.Entita;

namespace Sicurezza.Client.Manager
{
    public class FileManager
    {

        private static string reqsPath = ConfigurationManager.AppSettings["requests"];
        private static string keysPath = ConfigurationManager.AppSettings["keys"];
        private static string cacertPath = ConfigurationManager.AppSettings["cacert"];
        private static string certsPath = ConfigurationManager.AppSettings["certs"];
        private static string rensPath = ConfigurationManager.AppSettings["renews"];
        private static string revdPath = ConfigurationManager.AppSettings["revoked"];



        public static void SaveCertificate(X509Certificate Certificato, string path)
        {
            File.AppendAllText(path, Certificato.PEM);

        }

        public static void SaveRequest(string ReqId, string request, RSA key, string password)
        {
            string filepath = Path.Combine(reqsPath, ReqId + ".pem");
            File.AppendAllText(filepath, request);
            SavePrivateKey(ReqId, key, password, reqsPath);
        }

        public static void SavePrivateKey(string serial, RSA key, string password, string path)
        {
            string filepath = Path.Combine(path, serial + ".pem.key");
            BIO io = BIO.File(filepath, "w");
            new CryptoKey(key).WritePrivateKey(io, Cipher.DES_EDE3_CBC, password);
            io.SetClose(BIO.CloseOption.Close);
            io.Dispose();
        }

        public static string[] GetRequests()
        {
            string[] files = Directory.GetFiles(reqsPath, "*.pem");
            for (int i = 0; i < files.Length; i++)
            {
                files[i] = files[i].Replace(".pem", "").Split('\\')[1];
            }
            return files;

        }
        public static string LoadRequest(string ReqId)
        {
            return File.ReadAllText(Path.Combine(reqsPath, ReqId + ".pem"));
        }

        public static void MovePrivateKey(string ReqId, int serial)
        {
            if(ReqId.Contains("req-"))
            File.Move(Path.Combine(reqsPath, ReqId + ".pem.key"),
                      Path.Combine(keysPath, serial + ".pem.key"));
            else
                File.Move(Path.Combine(rensPath, ReqId + ".pem.key"),
                      Path.Combine(keysPath, serial + ".pem.key"));

        }

        public static void DeleteRequest(string ReqId)
        {
            File.Delete(Path.Combine(reqsPath, ReqId + ".pem"));
        }

        public static string LoadCaCert()
        {
            return File.ReadAllText(cacertPath);
        }

        internal static void SaveCertificate(int serial, string cert)
        {
            File.AppendAllText(Path.Combine(certsPath, serial.ToString() + ".pem"), cert);
        }

        public static string[] GetCertificates()
        {
            string[] files = Directory.GetFiles(certsPath, "*.pem");
            for (int i = 0; i < files.Length; i++)
            {
                files[i] = files[i].Replace(".pem", "").Split('\\')[1];
            }
            return files;
        }

        public static string LoadCertificate(string serial)
        {
            if (serial.Contains("ren-"))
                return File.ReadAllText(Path.Combine(rensPath, serial + ".pem"));
            else
                return File.ReadAllText(Path.Combine(certsPath, serial + ".pem"));
        }

        public static void DeletePrivateKey(string ReqId)
        {
            File.Delete(Path.Combine(keysPath, ReqId + ".pem.key"));
        }

        public static void RejectRequest(string ReqId)
        {
            File.Delete(Path.Combine(reqsPath, ReqId + ".pem"));
            File.Delete(Path.Combine(reqsPath, ReqId + ".pem.key"));
        }

        public static string LoadPrivateKey(int serial)
        {
            return File.ReadAllText(Path.Combine(keysPath, serial + ".pem.key"));
        }

        public static void SaveRequest(string RenId, int serial, RSA newkey, string password)
        {
            string filepath = Path.Combine(certsPath, serial.ToString() + ".pem");
            string newfilepath = Path.Combine(rensPath, RenId + ".pem");
            File.Move(filepath, newfilepath);
            SavePrivateKey(RenId, newkey, password, rensPath);
        }

        public static string[] GetRenews()
        {
            string[] files = Directory.GetFiles(rensPath, "*.pem");
            for (int i = 0; i < files.Length; i++)
            {
                files[i] = files[i].Replace(".pem", "").Split('\\')[1];
            }
            return files;
        }

        public static string LoadRenew(string ReqId)
        {
            return File.ReadAllText(Path.Combine(rensPath, ReqId + ".pem"));
        }

        public static void DeleteRenew(string ReqId)
        {
            File.Delete(Path.Combine(rensPath, ReqId + ".pem.key"));
            X509Certificate cert = new X509Certificate(new BIO(LoadCertificate(ReqId)));
            File.Move(Path.Combine(rensPath, ReqId + ".pem"), Path.Combine(revdPath, cert.SerialNumber + ".pem"));
        }

        public static void MoveToRevoked(int CertificateSerial)
        {
            File.Move(Path.Combine(certsPath, CertificateSerial + ".pem"), Path.Combine(revdPath, CertificateSerial + ".pem"));
        }

        public static string LoadCertificateFromFile(string filepath)
        {
            return File.ReadAllText(filepath);
        }

        public static byte[] GetFile(string filepath)
        {
            return File.ReadAllBytes(filepath);
        }

        public static string LoadFile(string filepath)
        {
            return File.ReadAllText(filepath);
        }


        public static void Delete(List<string> files)
        {
            for (int i = 0; i < files.Count; i++)
            {
                File.Delete(files[i]);
            }
        }

        public static string SaveTempFile(byte[] file, EncryptedFile encryptedFile)
        {
            string path = Path.Combine(Path.GetTempPath(), encryptedFile.Name);
            File.WriteAllBytes(path, file);
            return path;

        }

        public static void Copy(List<string> files, string path)
        {
            for (int i = 0; i < files.Count; i++)
            {
                File.Copy(files[i], Path.Combine(path, new FileInfo(files[i]).Name));
            }
        }

        public static List<EncryptedFile> GetFiles(List<string> files)
        {
            List<EncryptedFile> list = new List<EncryptedFile>();
            EncryptedFile ef = null;
            for (int i = 0; i < files.Count; i++)
            {
                ef = new EncryptedFile();
                ef.Name = new FileInfo(files[i]).Name;
                ef.File = File.ReadAllBytes(files[i]);
                list.Add(ef);
            }

            return list;
        }
    }
}
